#pragma once
#include<unordered_map>
#include<string>
#include "libdeflate_1/libdeflate.h"
extern struct libdeflate_compressor* compressor;
extern struct libdeflate_decompressor* decompressor;
typedef size_t(*CompressFunction)(libdeflate_compressor*,
const void*,size_t,void*,size_t);
typedef enum libdeflate_result(*DecompressFunction)(libdeflate_decompressor*,
const void*,size_t,void*,size_t,size_t*);
extern const std::string contenttype,keepalive,truestr,texthtml,GET,textcss,
	contentlength,charsetutf8,semicol,contentencoding,chunked,connection,
	lowerkeepalive,appjson,textplain,statusok,deflate,http1_1,gzip,zlib;
extern const std::unordered_map<std::string,std::string> supportformat;
extern const std::unordered_map<std::string,CompressFunction> supportcompress;
extern const std::unordered_map<std::string,DecompressFunction> supportdecompress;

struct Memory{
	char* data;
	size_t size;
	bool autofree;

	~Memory();
};

//一个文件（夹）一个Resource
struct Resource{
	enum res_type{
		res_dir=0,
		res_file,
		res_custom
	};
	const std::string name;
	const std::string& compressmethod;
	Resource(const char* n,const std::string& compressmethod);
	virtual ~Resource();
	//没找到返回nullptr
	virtual Resource* get(const char*)=0;
	virtual unsigned int type()=0;
	//默认不压缩 destsize压缩成功设置为压缩后大小
	virtual void compress(void* src,size_t srcsize,void* dest,size_t* destsize,
	const std::string& method="");
};
typedef std::unordered_map<std::string,Resource*> ResourceTable;
struct Dir:public Resource{
	ResourceTable children;
	~Dir()override;
	Resource* get(const char*)override;
	//一层相对路径 全英文
	Dir(const char* path,const char* name,const std::string& compressmethod);
	void print();
	unsigned int type()override;
};
struct File:public Resource{
	Memory memory;
	std::string extension;
	~File()override;
	//固定返回nullptr
	Resource* get(const char*)override;
	//一层相对路径 内存不足抛std::bad_alloc异常 默认读取deflate压缩版本
	File(const char* path,const char* name,const char* ext,const std::string& compressmethod);
	unsigned int type()override;
	//默认不压缩 destsize压缩成功设置为压缩后大小
	void compress(void* src,size_t srcsize,void* dest,size_t* destsize,
	const std::string& method="")override;
};

class StringTable:public std::unordered_map<std::string,std::string>{
	public:
	bool containkeyvalue(const std::string& k,const std::string& v);
	StringTable(std::initializer_list<std::pair<const std::string&,
	const std::string&>> v);
	StringTable();
};

bool openutil();
void closeutil();
